package com.exam.exam.controller;

import com.exam.exam.entity.User;
import com.exam.exam.repository.UserRepository;
import com.exam.exam.util.ExcelHelper;
import jakarta.persistence.criteria.Predicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserRepository userRepository;

    @Autowired
    public UserController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userRepository.save(user);
    }

    @GetMapping
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Integer id) {
        return userRepository.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Integer id, @RequestBody User user) {
        if (!userRepository.existsById(id)) {
            return ResponseEntity.notFound().build();
        }
        user.setId(id);
        return ResponseEntity.ok(userRepository.save(user));
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Integer id) {
        if (!userRepository.existsById(id)) {
            return ResponseEntity.notFound().build();
        }
        userRepository.deleteById(id);
        return ResponseEntity.noContent().build();
    }

    @PostMapping("/import")
    public ResponseEntity<Map<String, Object>> importUsers(@RequestParam("file") MultipartFile file) {
        Map<String, Object> response = new HashMap<>();

        if (!ExcelHelper.hasExcelFormat(file)) {
            response.put("success", false);
            response.put("message", "请上传Excel文件(.xlsx格式)");
            return ResponseEntity.badRequest().body(response);
        }

        try (InputStream inputStream = file.getInputStream()) {
            List<User> users = ExcelHelper.excelToUsers(inputStream);
            List<User> savedUsers = userRepository.saveAll(users);

            response.put("success", true);
            response.put("message", "成功导入 " + savedUsers.size() + " 条用户数据");
            response.put("data", savedUsers);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "导入失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }
    private Specification<User> buildUserSpecification(String username, Integer minId, Integer maxId) {
        return (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (username != null && !username.isEmpty()) {
                predicates.add(cb.like(root.get("username"), "%" + username + "%"));
            }
            if (minId != null) {
                predicates.add(cb.greaterThanOrEqualTo(root.get("id"), minId));
            }
            if (maxId != null) {
                predicates.add(cb.lessThanOrEqualTo(root.get("id"), maxId));
            }

            return predicates.isEmpty() ? null : cb.and(predicates.toArray(new Predicate[0]));
        };
    }

    @GetMapping("/search")
    public List<User> searchUsers(
            @RequestParam(required = false) String username,
            @RequestParam(required = false) Integer minId,
            @RequestParam(required = false) Integer maxId) {

        Specification<User> spec = buildUserSpecification(username, minId, maxId);
        return spec == null ? userRepository.findAll() : userRepository.findAll(spec);
    }

    @GetMapping("/export")
    public ResponseEntity<byte[]> exportUsers(
            @RequestParam(required = false) String username,
            @RequestParam(required = false) Integer minId,
            @RequestParam(required = false) Integer maxId) {

        Specification<User> spec = buildUserSpecification(username, minId, maxId);
        List<User> users = spec == null ? userRepository.findAll() : userRepository.findAll(spec);

        if (users.isEmpty()) {
            return ResponseEntity.noContent().build();
        }

        ByteArrayOutputStream stream = ExcelHelper.usersToExcel(users);
        byte[] bytes = stream.toByteArray();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        String filename = "users_export.xlsx";
        headers.setContentDispositionFormData("attachment", filename);

        return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
    }

}